HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux ip-172-26-0-120 6.17.0-1009-aws #9~24.04.2-Ubuntu SMP Fri Mar 6 23:50:29 UTC 2026 x86_64
User: ubuntu (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/dashboard.orbiwheels.com/app/Http/Controllers/Admin/BookingController.php
<?php

namespace App\Http\Controllers\Admin;

use App\DataTables\Admin\BookingDataTable;
use App\DataTables\Admin\BookingEnquiriesDataTable;
use App\DataTables\Admin\BookingRidesDataTable;
use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\BookingRide;
use App\Models\Customer;
use App\Models\Transporter;
use App\Models\Trip;
use App\Models\VehicleType;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class BookingController extends Controller
{
    public function index(BookingDataTable $dataTable)
    {
        return $dataTable->render('admin.booking.index');
    }
    public function enquiries_index(BookingEnquiriesDataTable $dataTable)
    {
        return $dataTable->render('admin.booking.enquiries');
    }

    public function oldview($id)
    {
        $booking = Booking::with(['rides.driver', 'transporter', 'customer'])->findOrFail(decrypt($id));

        return view('admin.booking.view', compact('booking'));
    }
      public function view($id, BookingRidesDataTable $dataTable)
    {
        $booking = Booking::findOrFail(decrypt($id)); 

        return $dataTable
            ->with('bookingId', $id)
            ->render('admin.booking.view', compact('booking'));
    }

    public function getRides($id, BookingRidesDataTable $dataTable)
    {
        $bookingId = decrypt($id);
        return $dataTable->with('bookingId', $bookingId)->ajax();
    }
    public function create()
    {
        $vehicleTypes = VehicleType::all();
        $customers = Customer::all();
        $transporters = Transporter::where('status', 1)->get();

        return view('admin.booking.create', compact('vehicleTypes', 'transporters', 'customers'));
    }
    public function store(Request $request)
{
    try {

        $validator = Validator::make($request->all(), [
            'customer_id'        => 'required|integer|exists:customers,id',
            'transporter_id'     => 'nullable|integer|exists:transporters,id',
            'ride_type'          => 'required|in:1,2,3,4,5,6',
            'booking_type'       => 'required|in:1,2',

            'trips'                     => 'required|array|min:1',
            'trips.*.vehicle_type'      => 'required|integer|exists:vehicle_types,id',
            'trips.*.pickup_location'   => 'required|string|max:255',
            'trips.*.pickup_lat'        => 'required|numeric',
            'trips.*.pickup_lng'        => 'required|numeric',
            'trips.*.drop_location'     => 'required|string|max:255',
            'trips.*.drop_lat'          => 'required|numeric',
            'trips.*.drop_lng'          => 'required|numeric',
            'trips.*.pickup_time'       => 'required|date_format:H:i',
            'trips.*.return_time'       => 'nullable|date_format:H:i|required_if:booking_type,2',
            'trips.*.dates'             => 'required|string', 
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        // Step 1: Create Booking
        $booking = Booking::create([
            'customer_id'          => $request->customer_id,
            'ride_type'            => $request->ride_type,
            'booking_type'         => $request->booking_type,
            'no_of_passengers'     => 1,
            'status'               => $request->transporter_id ?  BookingRide::ASSIGNED : BookingRide::PENDING,
            'total_customer_amount'=> 0,
            'transporter_id'       => $request->transporter_id ?? '',
        ]);

        $finalBookingTotal = 0;

        // Step 2: Loop Trips
        foreach ($request->trips as $tripData) {

            // Convert dates string → array
            $datesArray = explode(", ", $tripData['dates']);

            $vehicleType = VehicleType::findOrFail($tripData['vehicle_type']);

            $distance = getDistance(
                $tripData['pickup_lat'],
                $tripData['pickup_lng'],
                $tripData['drop_lat'],
                $tripData['drop_lng']
            );

            $fare       = getFare($distance, $vehicleType, "city");
            $commission = getCommission($distance);
            $gst        = get_gst_on_commission($commission);

            // Create Trip (one trip = many rides)
            $trip = Trip::create([
                'booking_id'       => $booking->id,
                'transporter_id'       => $request->transporter_id ?? '',
                'vehicle_type_id'  => $vehicleType->id,
                'ride_type'        => $request->ride_type,
                'booking_type'     => $request->booking_type,
                'dates'            => $datesArray,

                'times' => [
                    'pickup_time' => $tripData['pickup_time'],
                    'return_time' => $tripData['return_time'] ?? null,
                ],

                'locations' => [
                    'pickup_location' => $tripData['pickup_location'],
                    'pickup_lat'      => $tripData['pickup_lat'],
                    'pickup_lng'      => $tripData['pickup_lng'],
                    'drop_location'   => $tripData['drop_location'],
                    'drop_lat'        => $tripData['drop_lat'],
                    'drop_lng'        => $tripData['drop_lng'],
                ],

                'pricing_details' => [],
                'distance_km'     => $distance,
                'status'          => '0',
            ]);

            // Trip totals
            $tripFare = 0;
            $tripCommission = 0;
            $tripGst = 0;
            $tripTotal = 0;

            // Step 3: Create rides for each date inside Trip
            foreach ($datesArray as $date) {

                // ---- Onward ride ----
                $onward = $booking->rides()->create([
                    'trip_id'               => $trip->id,
                    'transporter_id'       => $request->transporter_id ?? '',
                    'vehicle_type_id'       => $vehicleType->id,
                    'locations'             => $trip->locations,
                    'ride_date'             => $date,
                    'pickup_time'           => $tripData['pickup_time'],
                    'ride_slot'             => getTimeSlot($tripData['pickup_time']),
                    'distance_km'           => $distance,
                    'fare'                  => $fare,
                    'ride_commission'       => $commission,
                    'gst_on_commission'     => $gst,
                    'total_customer_amount' => $fare + $commission + $gst,
                ]);

                $tripFare       += $fare;
                $tripCommission += $commission;
                $tripGst        += $gst;
                $tripTotal      += ($fare + $commission + $gst);

                // ---- Return Ride (only for booking_type = 2) ----
                if ($request->booking_type == 2 && !empty($tripData['return_time'])) {

                    $returnLocations = [
                        'pickup_location' => $tripData['drop_location'],
                        'pickup_lat'      => $tripData['drop_lat'],
                        'pickup_lng'      => $tripData['drop_lng'],
                        'drop_location'   => $tripData['pickup_location'],
                        'drop_lat'        => $tripData['pickup_lat'],
                        'drop_lng'        => $tripData['pickup_lng'],
                    ];

                    $return = $booking->rides()->create([
                        'trip_id'               => $trip->id,
                        'transporter_id'       => $request->transporter_id ?? '',
                        'vehicle_type_id'       => $vehicleType->id,
                        'locations'             => $returnLocations,
                        'ride_date'             => $date,
                        'pickup_time'           => $tripData['return_time'],
                        'ride_slot'             => getTimeSlot($tripData['return_time']),
                        'distance_km'           => $distance,
                        'fare'                  => $fare,
                        'ride_commission'       => $commission,
                        'gst_on_commission'     => $gst,
                        'total_customer_amount' => $fare + $commission + $gst,
                    ]);

                    $tripFare       += $fare;
                    $tripCommission += $commission;
                    $tripGst        += $gst;
                    $tripTotal      += ($fare + $commission + $gst);
                }
            }

            // Save totals in Trip
            $trip->update([
                'pricing_details' => [
                    'fare'         => $tripFare,
                    'commission'   => $tripCommission,
                    'gst'          => $tripGst,
                    'total_amount' => $tripTotal,
                ]
            ]);

            $finalBookingTotal += $tripTotal;
        }

        // Step 4: Update Booking Final Total
        $booking->update([
            'total_customer_amount' => $finalBookingTotal
        ]);

        return redirect()
            ->route('admin.booking.index')
            ->with('success', 'Booking created successfully!');

    } catch (\Exception $e) {
        return back()->with('error', $e->getMessage());
    }
}


    public function edit($id)
    {
        $booking = Booking::with(['trips','rides.driver', 'transporter', 'customer'])->findOrFail($id);
        $vehicleTypes = VehicleType::all();
        $customers = Customer::all();
        $transporters = Transporter::where('status', 1)->get();

        return view('admin.booking.edit', compact('booking', 'vehicleTypes','customers','transporters'));
    }
   public function update(Request $request, $id)
    {
        // dd($request->all());
        try {

            $validator = Validator::make($request->all(), [
                'ride_type'     => 'required|in:1,2,3,4,5,6',
                'booking_type'  => 'required|in:1,2',

                'trips'                     => 'required|array|min:1',
                'trips.*.vehicle_type'      => 'required|integer|exists:vehicle_types,id',
                'trips.*.pickup_location'   => 'required|string|max:255',
                'trips.*.pickup_lat'        => 'required|numeric',
                'trips.*.pickup_lng'        => 'required|numeric',
                'trips.*.drop_location'     => 'required|string|max:255',
                'trips.*.drop_lat'          => 'required|numeric',
                'trips.*.drop_lng'          => 'required|numeric',
                'trips.*.pickup_time'       => 'required|date_format:H:i',
                'trips.*.return_time'       => 'nullable|date_format:H:i|required_if:booking_type,2',
                'trips.*.dates'             => 'required|string',
            ]);

            if ($validator->fails()) {
                return back()->withErrors($validator)->withInput();
            }

            $booking = Booking::findOrFail($id);

            $booking->rides()->delete();
            $booking->trips()->delete();

            $booking->update([
                'ride_type' => $request->ride_type,
                'booking_type' => $request->booking_type,
                'vehicle_preferred' => null,
            ]);

            $finalBookingTotal = 0;

            foreach ($request->trips as $tripData) {

                $datesArray = explode(", ", $tripData['dates']);

                $vehicleType = VehicleType::findOrFail($tripData['vehicle_type']);

                $distance = getDistance(
                    $tripData['pickup_lat'],
                    $tripData['pickup_lng'],
                    $tripData['drop_lat'],
                    $tripData['drop_lng']
                );

                $fare       = getFare($distance, $vehicleType, "city");
                $commission = getCommission($distance);
                $gst        = get_gst_on_commission($commission);

                $trip = Trip::create([
                    'booking_id'       => $booking->id,
                    'transporter_id'       => $request->transporter_id ?? '',
                    'vehicle_type_id'  => $vehicleType->id,
                    'ride_type'        => $request->ride_type,
                    'booking_type'     => $request->booking_type,
                    'dates'            => $datesArray,

                    'times' => [
                        'pickup_time' => $tripData['pickup_time'],
                        'return_time' => $tripData['return_time'] ?? null,
                    ],

                    'locations' => [
                        'pickup_location' => $tripData['pickup_location'],
                        'pickup_lat'      => $tripData['pickup_lat'],
                        'pickup_lng'      => $tripData['pickup_lng'],
                        'drop_location'   => $tripData['drop_location'],
                        'drop_lat'        => $tripData['drop_lat'],
                        'drop_lng'        => $tripData['drop_lng'],
                    ],

                    'pricing_details' => [],
                    'distance_km'     => $distance,
                    'status'          => '0',
                ]);

                $tripFare = 0;
                $tripCommission = 0;
                $tripGst = 0;
                $tripTotal = 0;

                foreach ($datesArray as $date) {

                    $booking->rides()->create([
                        'trip_id'               => $trip->id,
                        'transporter_id'       => $request->transporter_id ?? '',
                        'vehicle_type_id'       => $vehicleType->id,
                        'locations'             => $trip->locations,
                        'ride_date'             => $date,
                        'pickup_time'           => $tripData['pickup_time'],
                        'ride_slot'             => getTimeSlot($tripData['pickup_time']),
                        'distance_km'           => $distance,
                        'fare'                  => $fare,
                        'ride_commission'       => $commission,
                        'gst_on_commission'     => $gst,
                        'total_customer_amount' => $fare + $commission + $gst,
                    ]);

                    $tripFare       += $fare;
                    $tripCommission += $commission;
                    $tripGst        += $gst;
                    $tripTotal      += ($fare + $commission + $gst);

                    if ($request->booking_type == 2 && !empty($tripData['return_time'])) {

                        $returnLocations = [
                            'pickup_location' => $tripData['drop_location'],
                            'pickup_lat'      => $tripData['drop_lat'],
                            'pickup_lng'      => $tripData['drop_lng'],
                            'drop_location'   => $tripData['pickup_location'],
                            'drop_lat'        => $tripData['pickup_lat'],
                            'drop_lng'        => $tripData['pickup_lng'],
                        ];

                        $booking->rides()->create([
                            'trip_id'               => $trip->id,
                            'transporter_id'       => $request->transporter_id ?? '',
                            'vehicle_type_id'       => $vehicleType->id,
                            'locations'             => $returnLocations,
                            'ride_date'             => $date,
                            'pickup_time'           => $tripData['return_time'],
                            'ride_slot'             => getTimeSlot($tripData['return_time']),
                            'distance_km'           => $distance,
                            'fare'                  => $fare,
                            'ride_commission'       => $commission,
                            'gst_on_commission'     => $gst,
                            'total_customer_amount' => $fare + $commission + $gst,
                        ]);

                        $tripFare       += $fare;
                        $tripCommission += $commission;
                        $tripGst        += $gst;
                        $tripTotal      += ($fare + $commission + $gst);
                    }
                }

                $trip->update([
                    'pricing_details' => [
                        'fare'         => $tripFare,
                        'commission'   => $tripCommission,
                        'gst'          => $tripGst,
                        'total_amount' => $tripTotal,
                    ]
                ]);

                $finalBookingTotal += $tripTotal;
            }
            $booking->update([
                'total_customer_amount' => $finalBookingTotal
            ]);

            return redirect()->route('admin.booking.index')->with('success', 'Booking updated successfully!');

        } catch (\Exception $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    public function search(Request $request)
    {
        $query = $request->get('q');

        $transporters = Transporter::query()
            ->when($query, function ($q) use ($query) {
                $q->where('company_name', 'like', "%{$query}%")
                    ->orWhere('first_name', 'like', "%{$query}%")
                    ->orWhere('last_name', 'like', "%{$query}%")
                    ->orWhere('email', 'like', "%{$query}%")
                    ->orWhere('phone', 'like', "%{$query}%");
            })
            ->limit(10)
            ->get();

        return response()->json($transporters);
    }

    public function assignTransporter(Request $request, $id)
    {
        $request->validate([
            'transporter_id' => 'required|exists:transporters,id',
        ]);

        $booking = Booking::with('trips.bookingRides')->findOrFail($id);

        $booking->update([
            'transporter_id' => $request->transporter_id
        ]);

        $booking->trips()->update([
            'transporter_id' => $request->transporter_id
        ]);

        foreach ($booking->trips as $trip) {
            $trip->bookingRides()->update([
                'transporter_id' => $request->transporter_id
            ]);
        }

        return response()->json([
            'status'  => true,
            'message' => 'Transporter updated for Booking, Trips, and Rides!',
        ]);
    }
   public function assignTransporterByTrip(Request $request, $id)
    {
        $trip = Trip::findOrFail($id);
        $transporterId = $request->transporter_id;

        if (!$trip->transporter_id) {
            $trip->update([
                'transporter_id' => $transporterId,
                'status' => Trip::ACCEPTED, 
            ]);
            $trip->bookingRides()->update([
                'transporter_id' => $transporterId,
            ]);
            return response()->json([
                'status'  => true,
                'message' => 'Transporter assigned successfully!',
            ]);
        }
        return response()->json([
            'status'  => false,
            'message' => 'This trip already has a transporter assigned.',
        ]);
    }


}